// 游戏流程控制
import {_decorator, Canvas, EventTouch, Node, Vec2, Label} from 'cc';
import {ecs} from "../framework/assets/libs/ecs/ECS";
import {CCComp} from "../common/cccomp";
import {smc} from "../config/singletonModule";
import {GridEntity} from "../ecs/gridEntity";
import {CellActionTime, GridSize} from "../cccomponent/enum";
import {ViewUtil} from "../framework/assets/core/utils/ViewUtil";
import {ListenComponent} from "../ecs/listenComponent";
import {GridInitComponent, SelectCellComponent} from "../ecs/utilsComponent";
import {CellEntity} from "db://assets/script/ecs/cellEntity";

const { ccclass, property } = _decorator;

// 监听用户操作
// 记录棋盘中的格子布局
// 判断格子是否可消除
// 实现方案: 新增 gridCheckSystem, 监听到新动作以后,开始检查是否可消,可消的话,再给每个 cell 添加动画组件,动效组件,播放音乐等
@ccclass('Controller')
export class Controller extends CCComp {
    reset(): void {
    }

    @property({
        type: Node,
        tooltip: '棋盘',
    })
    grid!: Node;

    @property({
        type: Node,
        tooltip: '分数',
    })
    score: Node;
    @property({
        type: Node,
        tooltip: '动效层',
    })
    effectLayer: Node;

    onLoad() {
        super.onLoad();
        // TODO check score
        this.score.getComponent(Label).string = '88888';
        smc.grid = ecs.getEntity<GridEntity>(GridEntity);
        smc.grid.GridModel.gridNode = this.grid;
        smc.grid.GridModel.effectLayer = this.effectLayer;
        // 初始化 grid
        smc.grid.add(GridInitComponent);
        // 监听移动
        this.grid.on(Node.EventType.TOUCH_START, this.onTouchStart.bind(this), this.grid);
        this.grid.on(Node.EventType.TOUCH_MOVE, this.onTouchMove.bind(this), this.grid);
    }

    onTouchStart(event: EventTouch) {
        if (!smc.grid.has(ListenComponent)) {
            // 不能监听用户操作
            return;
        }
        const pos = this.convertTouchPosToCell(event.getLocation());
        if (pos) {
            // 有效点击
            console.log(`click on (${pos.x}, ${pos.y})`);
            // 取消上次点击的格子
            let entity = this.getLastSelected();
            if (entity) {
                entity.click(false);
                smc.grid.GridModel.allowCellMove(entity);
            }
            entity = this.getCellEntityByPos(pos.x, pos.y);
            if (entity) {
                entity.click(true);
                smc.grid.GridModel.allowCellMove(entity);
                // 棋盘等待
                smc.grid.remove(ListenComponent);
            }
            smc.grid.GridModel.commitMovement();
        }
    }

    // 添加滑动效果
    onTouchMove(event: EventTouch) {
        if (!smc.grid.has(ListenComponent)) {
            return;
        }
        // 起始触点
        const startPos = this.convertTouchPosToCell(event.getStartLocation());
        // 移动中的触点
        const endPos = this.convertTouchPosToCell(event.getLocation());
        if (!startPos || !endPos) {
            return;
        }
        const delta = Math.abs(startPos.x - endPos.x) + Math.abs(startPos.y - endPos.y);
        if (delta !== 1) {
            // 不是相邻的格子
            return;
        }
        // 已经移动2个格子了, 不再监听 touchMove
        console.log(`moving (${startPos.x}, ${startPos.y}) -> (${endPos.x}, ${endPos.y})`)
        // 格子处于交换状态中, 且格子有 2 个
        let cellEntity = this.getCellEntityByPos(startPos.x, startPos.y)!;
        // 交换
        cellEntity.exchange();
        cellEntity.moveTo(endPos.x, endPos.y, CellActionTime.moveTo, 0);
        smc.grid.GridModel.allowCellMove(cellEntity);
        cellEntity = this.getCellEntityByPos(endPos.x, endPos.y)!;
        cellEntity.exchange();
        cellEntity.moveTo(startPos.x, startPos.y, CellActionTime.moveTo, 0);
        smc.grid.GridModel.allowCellMove(cellEntity);
        smc.grid.GridModel.exchangeCell(startPos.x, startPos.y, endPos.x, endPos.y);
        smc.grid.remove(ListenComponent);
        // 提交所有 cell
        smc.grid.GridModel.commitMovement();
    }

    getCellEntityByPos(x: number, y: number): CellEntity {
        const row = smc.grid.GridModel.cells[x];
        if (!row) {
            return null;
        }
        const cell = row[y];
        if (!cell) {
            return null;
        }
        return cell.cellEntity as CellEntity;
    }


    // 屏幕点击的位置转换为棋盘上的 cell
    convertTouchPosToCell(touchPos: Vec2) {
        // 屏幕触点转换为节点的本地坐标
        // 查找最上层的 gui 节点（带 canvas）
        const canvas = this.node.parent.parent.getComponent(Canvas);
        const localPos = ViewUtil.calculateScreenPosToSpacePos(canvas, touchPos, this.grid);

        if (localPos.x < 0 || localPos.x >= GridSize.gridWidth || localPos.y < 0 || localPos.y >= GridSize.gridHeight) {
            // 没有这个位置
            return null;
        }
        const x = GridSize.gridRows - Math.floor(localPos.y / (GridSize.offsetY + GridSize.cellHeight));
        const y = Math.floor(localPos.x / (GridSize.offsetX + GridSize.cellWidth)) + 1;
        return { x, y };
    }

    getLastSelected(): CellEntity {
        const entities = ecs.query(ecs.allOf(SelectCellComponent));
        if (entities.length > 1) {
            // 出错了，应该最多只有一个
            debugger;
        }
        if (entities.length === 1) {
            return entities[0] as CellEntity;
        }
        return null;
    }
}
